import csv
from io import StringIO
import pandas as pd
import json
import os
from flask import Blueprint, Response, jsonify, make_response, request, stream_with_context
from handle.logger import logger
from handle.products import *
from flask_cors import CORS,cross_origin

products_bp = Blueprint('products', __name__)

@products_bp.route('/', methods=['GET'])
def get_products():
    request_data={}
    request_data["name_list"]=[]
    request_data["page"]=int(request.args.get("page"))
    request_data["size"]=int(request.args.get("size"))
    request_data["status"]=request.args.get("status")
    request_data["IDlist"]=request.args.get("IDlist")
    
    name=request.args.get('name')
    if name!="" and name!=None:
        data,page_count,totalSize=get_product_list(request_data,name)
        return json.dumps({"status": 200,"message": "Get products list","page_count": page_count,"page": request_data["page"],"size": request_data["size"],"totalSize": totalSize,"data": data},sort_keys=False)
    else:
        data,page_count,totalSize=get_product_list(request_data,None)
        logger.error(request_data)
        return json.dumps({"status": 200,"message": "Get products list","page_count": page_count,"page": request_data["page"],"size": request_data["size"],"totalSize": totalSize,"data": data},sort_keys=False)



@products_bp.route('/csv/example', methods=['GET'])
def get_products_csv_exp():
    try:
        # 读取指定路径的 CSV 文件
        file_path = 'upload/csv/flattened_product_data.csv'
        products_data = pd.read_csv(file_path, encoding='gb18030')

        # 将 DataFrame 转换为 CSV 字符串（去掉 line_terminator 参数）
        csv_content = products_data.to_csv(index=False, sep=',')

        # 构建响应
        response = make_response(csv_content.encode('gb18030'))
        response.headers.set("Content-Disposition", "attachment", filename="products.csv")
        response.headers.set("Content-Type", "text/csv; charset=gb18030")

        return response

    except Exception as e:
        # 如果发生错误，返回错误信息
        return make_response({"status": 500, "message": f"Internal server error: {str(e)}"}, 500)



        
@products_bp.route('/csv', methods=['GET'])
def get_products_csv():
    request_data={}
    request_data["name_list"]=[]
    request_data["page"]=1
    request_data["size"]=9223372036854775807
    request_data["status"]=""
    request_data["IDlist"]=request.args.get("IDlist")
    # 创建 CSV 文件内容
    data,page_count,totalSize=get_product_list(request_data,None)
    fieldnames = ["ProductID", "Name", "Description", "Price", "Currency", "Country", "Status", "Remarks", "Cover","StockQuantity"]

    # 写入 CSV 文件到内存中
    csv_content = []
    csv_content.append(",".join(fieldnames))  # 写入表头
    for row in data:
        csv_content.append(",".join([str(row[field]) for field in fieldnames]))

    # 将 CSV 数据转换为字符串
    csv_data = "\r\n".join(csv_content).encode("gb18030")  # 使用 GB18030 编码

    # 构建响应
    response = make_response(csv_data)
    response.headers.set("Content-Disposition", "attachment", filename="products.csv")
    response.headers.set("Content-Type", "text/csv; charset=gb18030")

    # 返回响应
    return response

@products_bp.route('/csv', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_6():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/csv', methods=['POST'])
def get_products_csv_sx():
    request_data={}
    request_data["name_list"]=[]
    request_data["page"]=1
    request_data["size"]=9223372036854775807
    request_data["status"]=""
    request_data["IDlist"]=request.get_json()["IDlist"]
    # 创建 CSV 文件内容
    data,page_count,totalSize=get_product_list(request_data,None)
    fieldnames = ["ProductID", "Name", "Description", "Price", "Currency", "Country", "Status", "Remarks", "Cover","StockQuantity"]

    # 写入 CSV 文件到内存中
    csv_content = []
    csv_content.append(",".join(fieldnames))  # 写入表头
    for row in data:
        csv_content.append(",".join([str(row[field]) for field in fieldnames]))

    # 将 CSV 数据转换为字符串
    csv_data = "\r\n".join(csv_content).encode("gb18030")  # 使用 GB18030 编码

    # 构建响应
    response = make_response(csv_data)
    response.headers.set("Content-Disposition", "attachment", filename="products.csv")
    response.headers.set("Content-Type", "text/csv; charset=gb18030")

    # 返回响应
    return response

@products_bp.route('/upload', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_5():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return json.dumps({"status": 400,"message": "No file part in the request"}), 400

    file = request.files['file']

    if file.filename == '':
        return json.dumps({"status": 400,"message": "No file selected for uploading"}), 400

    if file and allowed_file(file.filename):
        filename = file.filename
        filepath = os.path.join(Config.UPLOAD_FOLDER, filename)
        file.save(filepath)
        filepath_str=filepath.replace('./',Config.URL)
        return json.dumps({"status": 200,"message": "File uploaded successfully","filepath": filepath.replace('./',""),"filepath_link": filepath_str},sort_keys=False)
    else:
        return json.dumps({"status": 400,"message": "Invalid file type"}), 400

@products_bp.route('/upload/csv', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_7():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/upload/csv', methods=['POST'])
@cross_origin()
def create_products_csv():
    # try:
        # 获取上传的文件
    uploaded_file = request.files.get('file')
    if not uploaded_file:
        return json.dumps({"status": 400, "message": "No file uploaded"}, sort_keys=False)

    # 读取CSV文件内容
    content = uploaded_file.read().decode('gb18030')  # 读取文件并解码为gb18030
    products_data = pd.read_csv(StringIO(content))

    # 验证数据是否包含必需字段
    required_fields = ["Name", "Description", "Price", "Currency", "Country", "SpecName", "SpecRemarks", "SubSpecName", "SubSpecRemarks"]
    missing_fields = [field for field in required_fields if field not in products_data.columns]
    if missing_fields:
        return json.dumps({"status": 400, "message": f"Missing required fields: {', '.join(missing_fields)}"}, sort_keys=False)

    # 验证数据格式是否正确
    errors = []
    for index, row in products_data.iterrows():
        try:
            # 检查每一行是否符合要求
            name = row["Name"]
            description = row["Description"] if "Description" in row else None
            price = float(row["Price"])
            currency = row["Currency"]
            country = row["Country"]
            remarks = row["Remarks"] if "Remarks" in row else None
            spec_name = row["SpecName"]
            spec_remarks = row["SpecRemarks"]
            sub_spec_name = row["SubSpecName"]
            sub_spec_remarks = row["SubSpecRemarks"]
        except Exception as e:
            error_message = {"row": index + 1, "error": str(e)}
            logger.error(f"Data validation error: {error_message}")
            errors.append(error_message)

    if errors:
        return json.dumps({"status": 400, "message": "Data validation failed", "errors": errors}, sort_keys=False)

    # 如果数据验证通过，将数据分组整理为嵌套结构
    grouped_data = {}
    for _, row in products_data.iterrows():
        product_key = (row["Name"], row["Description"], row["Price"], row["Currency"], row["Country"], row["Remarks"] if "Remarks" in row else None)
        if product_key not in grouped_data:
            grouped_data[product_key] = []
        grouped_data[product_key].append({
            "SpecName": row["SpecName"],
            "SpecRemarks": row["SpecRemarks"],
            "SubSpecName": row["SubSpecName"],
            "SubSpecRemarks": row["SubSpecRemarks"]
        })

    structured_data = []
    for key, specs in grouped_data.items():
        structured_data.append({
            "Name": key[0],
            "Description": key[1],
            "Price": key[2],
            "Currency": key[3],
            "Country": key[4],
            "Remarks": key[5],
            "Specification": specs,
            "Cover": ""
        })

    # 调用创建产品的函数
    for structured_data_item in structured_data:
        create_product(structured_data_item)
    return json.dumps({"status": 200, "message": "Products created successfully", "data": structured_data}, sort_keys=False)

    # except Exception as e:
        # logger.error(f"Unexpected error: {str(e)}")
        # return json.dumps({"status": 500, "message": f"Internal server error: {str(e)}"}, sort_keys=False)




@products_bp.route('/', methods=['OPTIONS'])
@cross_origin()
def handle_options_request():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response


@products_bp.route('/', methods=['POST'])
@cross_origin()
def create_products():
    products_data=request.get_json()
    logger.error(products_data)
    if products_data is None:
        return json.dumps({"status": 400,"message": "Bad request"},sort_keys=False)
    else:
        # data_str=products_data
        create_product(products_data)
        return json.dumps({"status": 200,"message": f"Create product","data": products_data},sort_keys=False)

@products_bp.route('/<product_id>', methods=['GET'])
def get_product(product_id):
    data=get_product_by_id(product_id)
    return json.dumps({"status": 200,"message": f"Get product {product_id}","data": data},sort_keys=False)


@products_bp.route('/<product_id>', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_1():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/<product_id>', methods=['PUT'])
def update_products(product_id):
    products_data={}
    products_data=request.get_json()
    products_data['ProductID']=product_id
    update_product(products_data)
    return json.dumps({"status": 200,"message": f"Update product {product_id}","data": products_data},sort_keys=False)

@products_bp.route('/dl', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_11():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response


@products_bp.route('/dl', methods=['DELETE'])
def delete_products_list():
    logger.error(request.headers.get('Content-Type'))
    request_data=request.get_json()
    logger.error(request.get_json())
    # request_data=request_data.get("IDlist",None)
    if request_data is None:
        return json.dumps({"status": 400,"message": "Bad request"},sort_keys=False)
    else:
        for product_id in request_data:
            delete_product(int(product_id))
        return json.dumps({"status": 200,"message": f"Delete product OK"},sort_keys=False)

@products_bp.route('/<product_id>', methods=['DELETE'])
def delete_products(product_id):
    delete_product(product_id)
    return json.dumps({"status": 200,"message": f"Delete product {product_id}"},sort_keys=False)


@products_bp.route('/variant/<SKU>', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_2():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/variant/<SKU>',methods=['PUT'])
def update_variant(SKU):
    variant_data=request.get_json()
    variant_data["SKU"]=SKU
    logger.info(variant_data)
    if update_product_variant(variant_data):
        return json.dumps({"status": 200,"message": f"Update product variant {SKU}","data": variant_data},sort_keys=False)
    else:
        return json.dumps({"status": 400,"message": f"Update product variant {SKU} failed"},sort_keys=False)
    
@products_bp.route('/specification/<products_id>',methods=['GET'])
def get_specification(products_id):
    data=get_product_specification(products_id)
    return json.dumps({"status": 200,"message": "Get specification list","data": data},sort_keys=False)

@products_bp.route('/specification/<SpecID>', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_3():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/specification/<SpecID>',methods=['PUT'])
def update_specification(SpecID):
    specification_data=request.get_json()
    specification_data["SpecID"]=SpecID
    if update_product_specification(specification_data):
        return json.dumps({"status": 200,"message": "update specification list","data": specification_data},sort_keys=False)


@products_bp.route('/subspecification/<SpecID>',methods=['GET'])
def get_subspecification(SpecID):
    data=get_product_subspecification(SpecID)
    return json.dumps({"status": 200,"message": "Get subspecification list","data": data},sort_keys=False)

@products_bp.route('/subspecification/<SubSpecID>', methods=['OPTIONS'])
@cross_origin()
def handle_options_request_4():
    response = jsonify({'message': 'This is the response to OPTIONS request'})
    response.headers.add('Access-Control-Allow-Methods', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

@products_bp.route('/subspecification/<SubSpecID>',methods=['PUT'])
def update_subspecification(SubSpecID):
    subspec_data=request.get_json()
    subspec_data["SubSpecID"]=SubSpecID
    if update_product_subspecification(subspec_data):
        return json.dumps({"status": 200,"message": "update subspecification list","data": subspec_data},sort_keys=False)
    
@products_bp.route('/SKU/<products_id>',methods=['GET'])
def get_SKU(products_id):
    data=get_product_SKU(products_id)
    return json.dumps({"status": 200,"message": "Get SKU list","data": data},sort_keys=False)